#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os
import sys

execfile(os.path.join(sys.path[0], "framework.py"))

from oriolusdocker.docker.requirements import InstallRequirements, RemoveRequirements, RemoveErrorType
from orioluspith.packets.meta import Meta
from orioluspith.packets.packet import FullName, Packet
from unittest import TestCase, TestLoader, TextTestRunner

class TestRequirements(TestCase):
    def test_check_install_requirements01(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

        mock_repository = MockRepository()
        test_packet = Packet(Meta("noname", "1.1.1.1", None, [], [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements02(self):
        class MockPacket:
            def __init__(self):
                self.name = "test_name-1.2.3.4"

        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return MockPacket()

        mock_repository = MockRepository()
        mock_packet = MockPacket()
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, mock_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements03(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return []

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "1.2.3.4"}, {"Name": "foo_packet", "Version": "1.3.3.4"}]

        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [], [], depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements04(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "1.2.3.4"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [], [], depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements05(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        replaces = [{"Name": "foo_packet", "Version": "1.2.3.4"}, ]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [], replaces, []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements06(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "[1.0.0.0,)"}, ]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [], [], depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements07(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "2.3.4.5", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "(, 2.0.0.0]"}, ]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [], [], depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements08(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "0.1.2.3", None, [], [], []))]

        mock_repository = MockRepository()
        replaces = [{"Name": "foo_packet", "Version": "[1.0.0.0,)"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [], replaces, []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements09(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        replaces = [{"Name": "foo_packet", "Version": "(, 2.0.0.0]"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [], replaces, []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements10(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        conflicts = [{"Name": "foo_packet", "Version": "1.2.3.4"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements11(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        conflicts = [{"Name": "foo_packet", "Version": "2.3.4.5"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements12(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        conflicts = [{"Name": "foo_packet", "Version": "[1.0.0.0,)"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements13(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "2.3.4.5", None, [], [], []))]

        mock_repository = MockRepository()
        conflicts = [{"Name": "foo_packet", "Version": "(, 2.0.0.0]"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements14(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "[1.0.0.0, 2.0.0.0]"}]
        replaces = [{"Name": "foo_packet2", "Version": "[0.0.0.0, 1.0.0.0]"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, [] , replaces, depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements15(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "[1.0.0.0, 2.0.0.0]"}]
        conflicts = [{"Name": "foo_packet2", "Version": "[0.0.0.0, 1.0.0.0]"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, [] , depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements16(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "[1.0.0.0, 2.0.0.0]"}]
        conflicts = [{"Name": "foo_packet2", "Version": "1.0.0.0"}]
        replaces = [{"Name": "foo_packet2", "Version": "[2.0.0.0,)"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, replaces , depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements17(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.9.0.0", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "[1.0.0.0, 2.0.0.0]"}]
        conflicts = [{"Name": "foo_packet", "Version": "[1.8.0.0, 3.0.0.0]"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, [] , depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements18(self):
        class MockRepository:
            def get_all(self):
                return []

            def find_packet_by_fullname(self, packet_name):
                return None

            def find_packets_by_name(self, packet_name):
                return [Packet(Meta("foo_packet", "1.7.0.0", None, [], [], []))]

        mock_repository = MockRepository()
        depends = [{"Name": "foo_packet", "Version": "[1.0.0.0, 2.0.0.0]"}]
        conflicts = [{"Name": "foo_packet", "Version": "[1.8.0.0, 3.0.0.0]"}]
        test_packet = Packet(Meta("test_packet", "1.2.3.4", None, conflicts, [], depends))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertTrue(can_install)

    def test_check_install_requirements19(self):
        class MockRepository:
            def get_all(self):
                conflicts = [{"Name": "test_packet", "Version": "[1.0.0.0, 2.0.0.0]"}]
                return [Packet(Meta("old_packet", "1.2.3.4", None, conflicts, [], [])), ]

            def find_packet_by_fullname(self, packet_name):
                return None

        mock_repository = MockRepository()
        test_packet = Packet(Meta("test_packet", "1.1.1.1", None, [], [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements20(self):
        class MockRepository:
            def get_all(self):
                replaces = [{"Name": "test_packet", "Version": "[1.0.0.0, 2.0.0.0]"}]
                return [Packet(Meta("old_packet", "1.2.3.4", None, [], replaces, [])), ]

            def find_packet_by_fullname(self, packet_name):
                return None

        mock_repository = MockRepository()
        test_packet = Packet(Meta("test_packet", "1.1.1.1", None, [], [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements21(self):
        class MockRepository:
            def get_all(self):
                conflicts = [{"Name": "test_packet", "Version": "1.1.1.1"}, {"Name": "packet", "Version": "1.0.0.0"}]
                return [Packet(Meta("old_packet", "1.2.3.4", None, conflicts, [], [])), ]

            def find_packet_by_fullname(self, packet_name):
                return None

        mock_repository = MockRepository()
        test_packet = Packet(Meta("test_packet", "1.1.1.1", None, [], [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_install_requirements22(self):
        class MockRepository:
            def get_all(self):
                replaces = [{"Name": "test_packet", "Version": "1.1.1.1"}, {"Name": "packet", "Version": "1.0.0.0"}]
                return [Packet(Meta("old_packet", "1.2.3.4", None, [], replaces, [])), ]

            def find_packet_by_fullname(self, packet_name):
                return None

        mock_repository = MockRepository()
        test_packet = Packet(Meta("test_packet", "1.1.1.1", None, [], [], []))
        requirements = InstallRequirements()

        can_install, reason = requirements.check(mock_repository, test_packet)
        self.assertFalse(can_install)

    def test_check_remove_requirements1(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return None

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "test-1.2.3.4")
        self.assertFalse(can_remove)
        self.assertEqual(RemoveErrorType.NoPacket, reason.type)

    def test_check_remove_requirements2(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return Packet(Meta("test_packet", "1.2.3.4", None, [], [], []))

            def find_child_packets(self, name):
                return [Packet(Meta("foo_packet", "1.2.3.4", None, [], [], [{"Name": "test_packet", "Version": "1.2.3.4"}])), 
                        Packet(Meta("foo_packet", "1.3.4.5", None, [], [], [{"Name": "test_packet", "Version": "1.2.3.4"}]))]

            def find_packets_by_name(self, name):
                return [Packet(Meta("test_packet", "1.2.3.4", None, [], [], []))]

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "test_packet-1.2.3.4")
        self.assertFalse(can_remove)
        self.assertEqual(RemoveErrorType.HasChildPackets, reason.type)
        self.assertEqual([FullName("foo_packet", "1.2.3.4"), FullName("foo_packet", "1.3.4.5")], reason.data)

    def test_check_remove_requirements3(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return Packet(Meta("test_packet", "1.2.3.4", None, [], [], []))

            def find_child_packets(self, name):
                return []

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "test_packet-1.2.3.4")
        self.assertTrue(can_remove)

    def test_check_remove_requirements4(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return Packet(Meta("packet_a", "1.2.3.1", None, [], [], []))

            def find_child_packets(self, name):
                return [Packet(Meta("parental_packet", "1.2.3.4", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]))] 

            def find_packets_by_name(self, name):
                return [Packet(Meta("packet_a", "1.2.3.1", None, [], [], [])), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []))]

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "packet_a-1.2.3.1")
        self.assertTrue(can_remove)

    def test_check_remove_requirements5(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return Packet(Meta("packet_a", "1.2.3.1", None, [], [], []))

            def find_child_packets(self, name):
                return [Packet(Meta("parental_packet", "1.2.3.4", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]))] 

            def find_packets_by_name(self, name):
                return [Packet(Meta("packet_a", "1.2.3.1", None, [], [], [])), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []))]

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "packet_a-1.2.3.2")
        self.assertTrue(can_remove)

    def test_check_remove_requirements6(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return Packet(Meta("packet_a", "1.2.3.1", None, [], [], []))

            def find_child_packets(self, name):
                return [Packet(Meta("parental_packet_a", "1.2.3.4", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}])),
                        Packet(Meta("parental_packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.1"}]))] 

            def find_packets_by_name(self, name):
                return [Packet(Meta("packet_a", "1.2.3.1", None, [], [], [])), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []))]

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "packet_a-1.2.3.1")
        self.assertFalse(can_remove)
        self.assertEqual(RemoveErrorType.HasChildPackets, reason.type)
        self.assertEqual([FullName("parental_packet_b", "2.3.4.5")], reason.data)

    def test_check_remove_requirements7(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return Packet(Meta("packet_a", "1.2.3.1", None, [], [], []))

            def find_child_packets(self, name):
                return [Packet(Meta("parental_packet_a", "1.2.3.4", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}])),
                        Packet(Meta("parental_packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]))] 

            def find_packets_by_name(self, name):
                return [Packet(Meta("packet_a", "1.2.3.2", None, [], [], [])), Packet(Meta("packet_a", "1.2.3.1", None, [], [], []))]

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "packet_a-1.2.3.1")
        self.assertTrue(can_remove)

    def test_check_remove_requirements8(self):
        class MockRepository:
            def find_packet_by_fullname(self, name):
                return Packet(Meta("packet_b", "2.3.4.5", None, [], [], []))

            def find_child_packets(self, name):
                return [Packet(Meta("parental_packet", "1.2.3.4", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.1"}, 
                                                                                 {"Name": "packet_b", "Version": "2.3.4.5"}]))]

            def find_packets_by_name(self, name):
                if name == "packet_a":
                    return [Packet(Meta("packet_a", "1.2.3.1", None, [], [], []))]

                return [Packet(Meta("packet_b", "2.3.4.5", None, [], [], []))]

        mock_repository = MockRepository()
        requirements = RemoveRequirements()

        can_remove, reason = requirements.check(mock_repository, "packet_b-2.3.4.5")
        self.assertFalse(can_remove)
        self.assertEqual(RemoveErrorType.HasChildPackets, reason.type)
        self.assertEqual([FullName("parental_packet", "1.2.3.4")], reason.data)

if __name__ == "__main__":
    suite = TestLoader().loadTestsFromTestCase(TestRequirements)
    TextTestRunner(verbosity=2).run(suite)